home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Skunkware 5
/
Skunkware 5.iso
/
src
/
X11
/
xpaint-2.1.1
/
operation.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-05-03
|
22KB
|
806 lines
/* +-------------------------------------------------------------------+ */
/* | Copyright 1992, 1993, David Koblas (koblas@netcom.com) | */
/* | | */
/* | Permission to use, copy, modify, and to distribute this software | */
/* | and its documentation for any purpose is hereby granted without | */
/* | fee, provided that the above copyright notice appear in all | */
/* | copies and that both that copyright notice and this permission | */
/* | notice appear in supporting documentation. There is no | */
/* | representations about the suitability of this software for | */
/* | any purpose. this software is provided "as is" without express | */
/* | or implied warranty. | */
/* | | */
/* +-------------------------------------------------------------------+ */
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Xaw/Form.h>
#include <X11/Xaw/SmeBSB.h>
#include <X11/Xaw/Box.h>
#include <X11/Xaw/Toggle.h>
#include <X11/Xaw/Viewport.h>
#include <X11/cursorfont.h>
#include <stdio.h>
#ifndef NOSTDHDRS
#include <stdlib.h>
#include <unistd.h>
#endif
#include "image.h"
#include "bitmaps/brushOp.xbm"
#include "bitmaps/brushOp.xpm"
#include "bitmaps/eraseOp.xbm"
#include "bitmaps/sprayOp.xbm"
#include "bitmaps/sprayOp.xpm"
#include "bitmaps/pencilOp.xbm"
#include "bitmaps/pencilOp.xpm"
#include "bitmaps/dotPenOp.xbm"
#include "bitmaps/dotPenOp.xpm"
#include "bitmaps/lineOp.xbm"
#include "bitmaps/arcOp.xbm"
#include "bitmaps/fillOp.xbm"
#include "bitmaps/fillOp.xpm"
#include "bitmaps/textOp.xbm"
#include "bitmaps/selectOp.xbm"
#include "bitmaps/boxOp.xbm"
#include "bitmaps/rayOp.xbm"
#include "bitmaps/fboxOp.xbm"
#include "bitmaps/ovalOp.xbm"
#include "bitmaps/fovalOp.xbm"
#include "bitmaps/lassoOp.xbm"
#include "bitmaps/clineOp.xbm"
#include "bitmaps/polyOp.xbm"
#include "bitmaps/fpolyOp.xbm"
#include "bitmaps/blobOp.xbm"
#include "bitmaps/fblobOp.xbm"
#include "bitmaps/selareaOp.xbm"
#include <xpm.h>
extern void AboutDialog(Widget);
#define OP_BEGIN 0
#define OP_END 1
#include "xpaint.h"
#include "misc.h"
#include "menu.h"
#include "Paint.h"
#include "text.h"
#include "ops.h"
static void changeLineAction(Widget, XEvent *);
static void changeSprayAction(Widget, XEvent *);
static void changeBrushAction(Widget, XEvent *);
static void changeChromaAction(Widget, XEvent *);
static void changeFontAction(Widget, XEvent *);
static void setOperation(Widget w, XtPointer opArg, XtPointer junk2)
{
Operation_t *op = (Operation_t*)opArg;
Operation_t stop, start;
if (op == CurrentOp)
return;
stop = CurrentOp ? CurrentOp[OP_END] : NULL;
start = op ? op [OP_BEGIN] : NULL;
GraphicSetOp((OperationRemoveProc)stop, (OperationAddProc)start);
CurrentOp = op;
}
/*
** The set line width callback pair
*/
static char currentLineWidth[10] = "1";
static void setWidth(Widget w, void *width)
{
XtVaSetValues(w, XtNlineWidth, (int)width, NULL);
}
static void okLineCallback(Widget w, XtPointer junk, XtPointer infoArg)
{
Arg arg;
TextPromptInfo *info = (TextPromptInfo*)infoArg;
int width = atoi(info->prompts[0].rstr);
if (width < 1 || width > 1000) {
Notice(w, "Invalid width, must be greater than zero and less than 1000");
return;
}
sprintf(currentLineWidth, "%d", width);
MenuCheckItem(w, True);
if (width == 1)
width = 0;
GraphicAll(setWidth, (void*)width);
XtSetArg(arg, XtNlineWidth, width);
OperationAddArg(arg);
}
static void lineWidth(Widget w, int width)
{
String lbl;
XtVaGetValues(w, XtNlabel, &lbl, NULL);
width = atoi(lbl);
if (width <= 0) {
static TextPromptInfo info;
static struct textPromptInfo value[1];
value[0].prompt = "Width:";
value[0].str = currentLineWidth;
value[0].len = 4;
info.prompts = value;
info.title = "Enter desired line width";
info.nprompt = 1;
TextPrompt(w, "linewidth", &info, okLineCallback, NULL, NULL);
} else {
Arg arg;
if (width == 1)
width = 0;
MenuCheckItem(w, True);
GraphicAll(setWidth, (void *)width);
XtSetArg(arg, XtNlineWidth, width);
OperationAddArg(arg);
}
}
/*
**
*/
static char sprayDensityStr[10] = "10";
static char sprayRadiusStr[10] = "10";
static char sprayRateStr[10] = "10";
static void sprayOkCallback(Widget w, XtPointer junk, XtPointer infoArg)
{
void SpraySetParameters(int, int, int);
TextPromptInfo *info = (TextPromptInfo*)infoArg;
int radius = atoi(info->prompts[0].rstr);
int density = atoi(info->prompts[1].rstr);
int rate = atoi(info->prompts[2].rstr);
if (radius < 1 || radius > 100) {
Notice(w, "Radius should be between 1 and 100");
return;
}
if (density < 1 || density > 500) {
Notice(w, "Density should be between 1 and 500");
return;
}
if (rate < 1 || rate > 500) {
Notice(w, "Rate should be between 1 and 500");
return;
}
SpraySetParameters(radius, density, rate);
sprintf(sprayDensityStr,"%d",density);
sprintf(sprayRadiusStr,"%d",radius);
sprintf(sprayRateStr,"%d",rate);
}
static void sprayMenuCallback(Widget w)
{
static TextPromptInfo info;
static struct textPromptInfo value[3];
value[0].prompt = "Radius:";
value[0].str = sprayRadiusStr;
value[0].len = 4;
value[1].prompt = "Density:";
value[1].str = sprayDensityStr;
value[1].len = 4;
value[2].prompt = "Rate:";
value[2].str = sprayRateStr;
value[2].len = 4;
info.prompts = value;
info.title = "Enter the desired spray parameters";
info.nprompt = 3;
TextPrompt(w, "sprayparams", &info, sprayOkCallback, NULL, NULL);
}
/*
** Font menu callbacks.
*/
static void fontSetCallback(Widget paint, void *info)
{
XtVaSetValues(paint, XtNfont, (XFontStruct*)info, NULL);
FontChanged(paint);
}
static void fontSet(Widget w, char *name)
{
XFontStruct *info;
Arg arg;
if (name == NULL) {
FontSelect(w, None);
} else {
if ((info = XLoadQueryFont(XtDisplay(GetShell(w)), name)) == NULL) {
XtVaSetValues(w, XtNsensitive, False, NULL);
Notice(w, "Unable to load requested font");
return;
}
GraphicAll(fontSetCallback, (void*)info);
XtSetArg(arg, XtNfont, info);
OperationAddArg(arg);
}
MenuCheckItem(w, True);
}
/*
** Exit callback (simple)
*/
static void exitOkCallback(Widget w, XtPointer junk, XtPointer junk2)
{
#if 0
XtDestroyWidget(GetToplevel(w));
XtDestroyApplicationContext(XtWidgetToApplicationContext(w));
Global.timeToDie = True;
#else
exit(0);
#endif
}
static void exitCancelCallback(Widget paint, XtPointer junk, XtPointer junk2)
{
}
static void exitPaintCheck(Widget paint, void *sumArg)
{
int *sum = (int *)sumArg;
Boolean flg;
XtVaGetValues(paint, XtNdirty, &flg, NULL);
*sum += flg ? 1 : 0;
}
static void exitPaint(Widget w, XtPointer junk, XtPointer junk2)
{
int total = 0;
GraphicAll(exitPaintCheck, (void*)&total);
if (total == 0) {
exitOkCallback(w, NULL, NULL);
return;
}
AlertBox(w, "There are unsaved changes,\nare you sure you wish to quit?",
exitOkCallback, exitCancelCallback, NULL);
}
/*
**
*/
extern void ClipboardSetImage(Widget, void *);
static void loadClipboardCB(Widget w, char *file, void *image)
{
ClipboardSetImage(w, image);
}
static void loadClipboard(Widget w, XtPointer junk, XtPointer junk2)
{
GetFileName(GetShell(w), 0, NULL, (XtCallbackProc)loadClipboardCB, NULL);
}
/*
** Button popus
*/
static void erasePopupCB(Widget w, XtPointer junk, XtPointer junk2);
static void fillPopupCB(Widget w, XtPointer junk, XtPointer junk2);
static void selectPopupCB(Widget w, XtPointer junk, XtPointer junk2);
static void sprayPopupCB(Widget w, XtPointer junk, XtPointer junk2);
static void ovalPopupCB(Widget w, XtPointer junk, XtPointer junk2);
static void boxPopupCB(Widget w, XtPointer junk, XtPointer junk2);
#define GENERATE_HELP(name, hlpstr) \
static PaintMenuItem name [] = { \
MI_SEPERATOR(), \
MI_SIMPLECB("help", HelpDialog, hlpstr) \
};
static PaintMenuItem brushPopup[] = {
MI_SEPERATOR(),
MI_SIMPLECB("select", BrushSelect, NULL),
MI_SIMPLECB("help", HelpDialog, "toolbox.tools.brush"),
};
static PaintMenuItem erasePopup[] = {
MI_SEPERATOR(),
MI_FLAGCB("original", MF_CHECKON, erasePopupCB, 0),
MI_SIMPLECB("select", changeBrushAction, NULL),
MI_SIMPLECB("help", HelpDialog, "toolbox.tools.erase"),
};
static PaintMenuItem sprayPopup[] = {
MI_SEPERATOR(),
MI_FLAGCB("gauss", MF_CHECKON, sprayPopupCB, 0),
MI_SIMPLECB("select", changeSprayAction, NULL),
MI_SIMPLECB("help", HelpDialog, "toolbox.tools.spray"),
};
GENERATE_HELP(pencilPopup, "toolbox.tools.pencil")
GENERATE_HELP(dotPencilPopup, "toolbox.tools.dotPencil")
GENERATE_HELP(linePopup, "toolbox.tools.line")
GENERATE_HELP(rayPopup, "toolbox.tools.ray")
GENERATE_HELP(arcPopup, "toolbox.tools.arc")
static PaintMenuItem fillPopup[] = {
MI_SEPERATOR(),
MI_FLAGCB("fill", MF_CHECKON|MF_GROUP1, fillPopupCB, 0),
MI_FLAGCB("change", MF_CHECK|MF_GROUP1, fillPopupCB, 1),
MI_SIMPLECB("help", HelpDialog, "toolbox.tools.fill"),
};
static PaintMenuItem textPopup[] = {
MI_SEPERATOR(),
MI_SIMPLECB("select", changeFontAction, NULL),
MI_SIMPLECB("help", HelpDialog, "toolbox.tools.text"),
};
GENERATE_HELP(polyPopup, "toolbox.tools.poly")
GENERATE_HELP(freehandPopup, "toolbox.tools.blob")
GENERATE_HELP(clinePopup, "toolbox.tools.cline")
static PaintMenuItem selectBPopup[] = {
MI_SEPERATOR(),
MI_FLAGCB("shape", MF_CHECKON|MF_GROUP1, selectPopupCB, 0),
MI_FLAGCB("not_color", MF_CHECK|MF_GROUP1, selectPopupCB, 1),
MI_FLAGCB("only_color", MF_CHECK|MF_GROUP1, selectPopupCB, 2),
MI_SIMPLECB("select", changeChromaAction, NULL),
MI_SIMPLECB("help", HelpDialog, "toolbox.tools.select"),
};
static PaintMenuItem selectAPopup[] = {
MI_SEPERATOR(),
MI_FLAGCB("shape", MF_CHECKON|MF_GROUP1, selectPopupCB, 0),
MI_FLAGCB("not_color", MF_CHECK|MF_GROUP1, selectPopupCB, 1),
MI_FLAGCB("only_color", MF_CHECK|MF_GROUP1, selectPopupCB, 2),
MI_SIMPLECB("select", changeChromaAction, NULL),
MI_SIMPLECB("help", HelpDialog, "toolbox.tools.select"),
};
static PaintMenuItem boxPopup[] = {
MI_SEPERATOR(),
MI_FLAGCB("center", MF_CHECK, boxPopupCB, 0),
MI_SIMPLECB("help", HelpDialog, "toolbox.tools.box"),
};
static PaintMenuItem fboxPopup[] = {
MI_SEPERATOR(),
MI_FLAGCB("center", MF_CHECK, boxPopupCB, 0),
MI_SIMPLECB("help", HelpDialog, "toolbox.tools.box"),
};
static PaintMenuItem ovalPopup[] = {
MI_SEPERATOR(),
MI_FLAGCB("center", MF_CHECK, ovalPopupCB, 0),
MI_SIMPLECB("help", HelpDialog, "toolbox.tools.oval"),
};
static PaintMenuItem fovalPopup[] = {
MI_SEPERATOR(),
MI_FLAGCB("center", MF_CHECK, ovalPopupCB, 0),
MI_SIMPLECB("help", HelpDialog, "toolbox.tools.oval"),
};
static void ovalPopupCB(Widget w, XtPointer junk, XtPointer junk2)
{
Boolean m = !CircleGetStyle();
CircleSetStyle(m);
MenuCheckItem(ovalPopup[1].widget, m);
MenuCheckItem(fovalPopup[1].widget, m);
}
static void boxPopupCB(Widget w, XtPointer junk, XtPointer junk2)
{
Boolean m = !BoxGetStyle();
BoxSetStyle(m);
MenuCheckItem(boxPopup[1].widget, m);
MenuCheckItem(fboxPopup[1].widget, m);
}
static void fillPopupCB(Widget w, XtPointer junk, XtPointer junk2)
{
int nm = (int)junk;
FillSetMode(nm);
MenuCheckItem(fillPopup[nm + 1].widget, True);
}
static void selectPopupCB(Widget w, XtPointer junk, XtPointer junk2)
{
int n = (int)junk;
MenuCheckItem(selectAPopup[n + 1].widget, True);
MenuCheckItem(selectBPopup[n + 1].widget, True);
SelectSetCutMode(n);
}
void OperationSelectCallAcross(int n)
{
MenuCheckItem(selectAPopup[n + 1].widget, True);
MenuCheckItem(selectBPopup[n + 1].widget, True);
}
static void sprayPopupCB(Widget w, XtPointer junk, XtPointer junk2)
{
Boolean m = !SprayGetStyle();
SpraySetStyle(m);
MenuCheckItem(w, m);
}
static void erasePopupCB(Widget w, XtPointer junk, XtPointer junk2)
{
Boolean m = !EraseGetMode();
EraseSetMode(m);
MenuCheckItem(w, m);
}
/*
** Done with operation popup menus
*/
#define GENERATE_OP(name) \
extern void *CONCAT(name,Add)(Widget w,...), \
*CONCAT(name,Remove)(Widget w,...); \
static Operation_t CONCAT(name,Op)[] = { \
CONCAT(name,Add), CONCAT(name,Remove) \
};
GENERATE_OP(DotPencil)
GENERATE_OP(Pencil)
GENERATE_OP(Box)
GENERATE_OP(FBox)
GENERATE_OP(Line)
GENERATE_OP(Ray)
GENERATE_OP(Arc)
GENERATE_OP(Oval)
GENERATE_OP(FOval)
GENERATE_OP(Erase)
GENERATE_OP(Brush)
GENERATE_OP(Font)
GENERATE_OP(Smear)
GENERATE_OP(Spray)
GENERATE_OP(Poly)
GENERATE_OP(FPoly)
GENERATE_OP(Freehand)
GENERATE_OP(FFreehand)
GENERATE_OP(CLine)
GENERATE_OP(Fill)
GENERATE_OP(SelectBox)
GENERATE_OP(SelectArea)
#if 0
GENERATE_OP(SelectChroma)
#endif
#define BITMAP(name) \
NULL, (char *)CONCAT(name,Op_bits) , CONCAT(name,Op_width), CONCAT(name,Op_height)
#define XPMMAP(name) \
(char **)CONCAT(name,Op_xpm) , NULL , CONCAT(name,Op_width), CONCAT(name,Op_height)
#define MENU(name) XtNumber(CONCAT(name,Popup)), CONCAT(name,Popup)
typedef struct {
char *name;
char **xpmmap;
char *bitmap;
int width, height;
void (*callback)(); /* By default setOperation() */
void *data;
char *translations;
int nitems;
PaintMenuItem *popupMenu;
Pixmap icon;
} IconListItem;
static Widget iconListWidget;
static IconListItem iconList[] = {
{ "brush", XPMMAP(brush), NULL, BrushOp,
"<BtnDown>(2): changeBrush()", MENU(brush), None },
{ "erase", BITMAP(erase), NULL, EraseOp,
"<BtnDown>(2): changeBrush()", MENU(erase), None },
{ "selectBox", BITMAP(select), NULL, SelectBoxOp,
"<BtnDown>(2): changeChroma()", MENU(selectB), None },
{ "selectArea", BITMAP(selarea), NULL, SelectAreaOp,
"<BtnDown>(2): changeChroma()", MENU(selectA), None },
{ "pencil", XPMMAP(pencil), NULL, PencilOp,
NULL, MENU(pencil), None },
{ "dotPencil", XPMMAP(dotPencil), NULL, DotPencilOp,
NULL, MENU(dotPencil), None },
{ "spray", XPMMAP(spray), NULL, SprayOp,
"<BtnDown>(2): changeSpray()", MENU(spray), None },
{ "fill", XPMMAP(fill), NULL, FillOp,
NULL, MENU(fill), None },
{ "text", BITMAP(text), NULL, FontOp,
"<BtnDown>(2): changeFont()", MENU(text), None },
{ "line", BITMAP(line), NULL, LineOp,
NULL, MENU(line), None },
{ "ray", BITMAP(ray), NULL, RayOp,
NULL, MENU(ray), None },
{ "arc", BITMAP(arc), NULL, ArcOp,
NULL, MENU(arc), None },
{ "box", BITMAP(box), NULL, BoxOp,
NULL, MENU(box), None },
{ "fBox", BITMAP(fbox), NULL, FBoxOp,
NULL, MENU(fbox), None },
{ "oval", BITMAP(oval), NULL, OvalOp,
NULL, MENU(oval), None },
{ "fOval", BITMAP(foval), NULL, FOvalOp,
NULL, MENU(foval), None },
{ "cLine", BITMAP(cline), NULL, CLineOp,
NULL, MENU(cline), None },
{ "polygon", BITMAP(poly), NULL, PolyOp,
NULL, MENU(poly), None },
{ "fPolygon", BITMAP(fpoly), NULL, FPolyOp,
NULL, MENU(poly), None },
{ "freehand", BITMAP(freehand), NULL, FreehandOp,
NULL, MENU(freehand), None },
{ "fFreehand", BITMAP(ffreehand), NULL, FFreehandOp,
NULL, MENU(freehand), None },
};
void OperationSet(String names[], int num)
{
IconListItem *match = NULL;
int i, j;
for (i = 0; i < XtNumber(iconList); i++) {
for (j = 0; j < num; j++) {
if (strcmp(names[j], iconList[i].name) == 0) {
if (match == NULL)
match = &iconList[i];
if (CurrentOp == iconList[i].data)
return;
}
}
}
if (match != NULL)
XawToggleSetCurrent(iconListWidget, (XtPointer)match->name);
}
static PaintMenuItem lineMenu[] = {
#if 0
MI_FLAGCB("0", MF_CHECK|MF_GROUP1, lineWidth, NULL),
#endif
MI_FLAGCB("1", MF_CHECK|MF_GROUP1, lineWidth, NULL),
MI_FLAGCB("2", MF_CHECK|MF_GROUP1, lineWidth, NULL),
MI_FLAGCB("4", MF_CHECK|MF_GROUP1, lineWidth, NULL),
MI_FLAGCB("6", MF_CHECK|MF_GROUP1, lineWidth, NULL),
MI_FLAGCB("8", MF_CHECK|MF_GROUP1, lineWidth, NULL),
#define LW_SELECT 5
MI_FLAGCB("select", MF_CHECK|MF_GROUP1, lineWidth, NULL),
};
static PaintMenuItem fontMenu[] = {
MI_FLAGCB("Times 8", MF_CHECK|MF_GROUP1,
fontSet, "-*-times-medium-r-normal-*-*-80-*-*-p-*-*-*"),
MI_FLAGCB("Times 12", MF_CHECK|MF_GROUP1,
fontSet, "-*-times-medium-r-normal-*-*-120-*-*-p-*-*-*"),
MI_FLAGCB("Times 18", MF_CHECK|MF_GROUP1,
fontSet, "-*-times-medium-r-normal-*-*-180-*-*-p-*-*-*"),
MI_FLAGCB("Times Bold 12", MF_CHECK|MF_GROUP1,
fontSet, "-*-times-bold-r-normal-*-*-120-*-*-p-*-*-*"),
MI_FLAGCB("Times Italic 12", MF_CHECK|MF_GROUP1,
fontSet, "-*-times-bold-i-normal-*-*-120-*-*-p-*-*-*"),
MI_FLAGCB("Lucida 12", MF_CHECK|MF_GROUP1,
fontSet, "-*-lucida-medium-r-normal-*-*-120-*-*-p-*-*-*"),
MI_FLAGCB("Helvetica 12", MF_CHECK|MF_GROUP1,
fontSet, "-*-helvetica-medium-r-normal-*-*-120-*-*-p-*-*-*"),
MI_FLAGCB("Helvetica Bold 12", MF_CHECK|MF_GROUP1,
fontSet, "-*-helvetica-bold-r-normal-*-*-120-*-*-p-*-*-*"),
MI_FLAGCB("Fixed 12", MF_CHECK|MF_GROUP1,
fontSet, "-*-fixed-medium-r-normal-*-*-120-*-*-m-*-*-*"),
MI_FLAGCB("Courier 12", MF_CHECK|MF_GROUP1,
fontSet, "-*-courier-medium-r-normal-*-*-120-*-*-m-*-*-*"),
MI_SEPERATOR(),
#define FM_SELECT 11
MI_FLAGCB("select", MF_CHECK|MF_GROUP1, fontSet, NULL),
};
static PaintMenuItem otherMenu[] = {
MI_SIMPLECB("brushSelect", BrushSelect, NULL),
#define SP_SELECT 1
MI_SIMPLECB("sprayEdit", sprayMenuCallback, NULL),
};
static PaintMenuItem fileMenu[] = {
MI_SIMPLECB("new", GraphicCreate, 0),
MI_SIMPLECB("new-size", GraphicCreate, 2),
MI_SIMPLECB("open", GraphicCreate, 1),
MI_SIMPLECB("load-clip", loadClipboard, NULL),
MI_SEPERATOR(),
MI_SIMPLECB("quit", exitPaint, NULL),
};
static PaintMenuItem helpMenu[] = {
MI_SIMPLECB("about", HelpDialog, "about"),
MI_SEPERATOR(),
MI_SIMPLECB("help", HelpDialog, "toolbox.toolbox"),
};
static PaintMenuBar menuBar[] = {
{ None, "file", XtNumber(fileMenu), fileMenu },
#if 0
{ None, "other", XtNumber(otherMenu), otherMenu },
#endif
{ None, "line", XtNumber(lineMenu), lineMenu },
{ None, "font", XtNumber(fontMenu), fontMenu },
{ None, "help", XtNumber(helpMenu), helpMenu },
};
/*
** Now for the callback functions
*/
static int argListLen = 0;
static Arg *argList;
void OperationSetPaint(Widget paint)
{
XtSetValues(paint, argList, argListLen);
}
void OperationAddArg(Arg arg)
{
int i;
for (i = 0; i < argListLen; i++) {
if (strcmp(argList[i].name, arg.name) == 0) {
argList[i].value = arg.value;
return;
}
}
if (argListLen == 0)
argList = (Arg *)XtMalloc(sizeof(Arg) * 2);
else
argList = (Arg *)XtRealloc((XtPointer)argList, sizeof(Arg) * (argListLen + 2));
argList[argListLen++] = arg;
}
/*
** Double click action callback functions.
*/
static void changeLineAction(Widget w, XEvent *event)
{
lineWidth(lineMenu[LW_SELECT].widget, (int)lineMenu[LW_SELECT].data);
}
static void changeSprayAction(Widget w, XEvent *event)
{
sprayMenuCallback(w);
}
static void changeBrushAction(Widget w, XEvent *event)
{
BrushSelect(w);
}
static void changeChromaAction(Widget w, XEvent *event)
{
SelectChromaDialog(w);
}
static void changeFontAction(Widget w, XEvent *event)
{
fontSet(fontMenu[FM_SELECT].widget, (char *)fontMenu[FM_SELECT].data);
}
/*
** The real init function
*/
void OperationInit(Widget toplevel)
{
static XtActionsRec acts[] = {
{ "changeLine", (XtActionProc)changeLineAction },
{ "changeBrush", (XtActionProc)changeBrushAction },
{ "changeFont", (XtActionProc)changeFontAction },
{ "changeSpray", (XtActionProc)changeSprayAction },
{ "changeChroma", (XtActionProc)changeChromaAction },
};
int i;
Pixmap pix;
Widget vport, form, box, icon, bar, firstIcon = None;
Pixel fg, bg;
char *defTrans = "<BtnDown>,<BtnUp>: set() notify()\n";
XtTranslations trans = XtParseTranslationTable(defTrans);
IconListItem *cur;
form = XtVaCreateManagedWidget("toolbox",
formWidgetClass, toplevel,
XtNborderWidth, 0,
NULL);
XtAppAddActions(XtWidgetToApplicationContext(toplevel), acts, XtNumber(acts));
/*
** Create the menu bar
*/
bar = MenuBarCreate(form, XtNumber(menuBar), menuBar);
/*
** Create the operation icon list
*/
vport = XtVaCreateManagedWidget("vport",
viewportWidgetClass, form,
XtNallowVert, True,
XtNuseRight, True,
XtNfromVert, bar,
NULL);
box = XtVaCreateManagedWidget("box",
boxWidgetClass, vport,
XtNwidth, 32 * 8,
XtNtop, XtChainTop,
NULL);
for (i = 0; i < XtNumber(iconList); i++) {
cur = &iconList[i];
icon = XtVaCreateManagedWidget(cur->name,
toggleWidgetClass, box,
XtNtranslations, trans,
XtNradioGroup, firstIcon,
XtNradioData, cur->name,
NULL);
if (cur->bitmap != NULL) {
XtVaGetValues(icon, XtNforeground, &fg,
XtNbackground, &bg,
NULL);
bg = WhitePixelOfScreen(XtScreen(box));
fg = BlackPixelOfScreen(XtScreen(box));
pix = XCreatePixmapFromBitmapData(
XtDisplay(box),
DefaultRootWindow(XtDisplay(box)),
cur->bitmap,
cur->width,
cur->height,
fg, bg,
DefaultDepthOfScreen(XtScreen(box)));
} else if (cur->xpmmap != NULL) {
XpmCreatePixmapFromData(
XtDisplay(box),
DefaultRootWindow(XtDisplay(box)),
cur->xpmmap,
&pix, NULL, NULL);
} else {
pix = None;
}
cur->icon = pix;
if (pix != None)
XtVaSetValues(icon, XtNbitmap, pix, NULL);
if (cur->translations != NULL) {
XtTranslations moreTrans;
moreTrans = XtParseTranslationTable(cur->translations);
XtAugmentTranslations(icon, moreTrans);
}
if (firstIcon == NULL) {
XtVaSetValues(icon, XtNstate, True, NULL);
setOperation(icon, cur->data, NULL);
firstIcon = icon;
iconListWidget = icon;
}
if (cur->callback != NULL)
XtAddCallback(icon, XtNcallback,
cur->callback, cur->data);
else
XtAddCallback(icon, XtNcallback,
setOperation, cur->data);
#if 1
if (cur->nitems != 0 && cur->popupMenu != NULL)
MenuPopupCreate(icon, cur->nitems, cur->popupMenu);
#endif
}
lineWidth(lineMenu[0].widget, (int)lineMenu[0].data);
fontSet(fontMenu[1].widget, fontMenu[1].data);
AddDestroyCallback(toplevel,
(void (*)(Widget, void *, XEvent *))exitPaint, NULL);
}
Image *OperationIconImage(Widget w, char *name)
{
Image *img;
int i;
for (i = 0; i < XtNumber(iconList); i++)
if (strcmp(name, iconList[i].name) == 0)
break;
if (i == XtNumber(iconList) || iconList[i].icon == None)
return NULL;
return PixmapToImage(w, iconList[i].icon, None);
}